HBase 以及 Python 使用 HBase
HBase 的支持的文件系统是 HDFS,但其不仅仅支持 HDFS。由于其使用的文件系统是可插拔的架构,只需要提供可以被 Hadoop 接口支持的文件系统那么就可以替换 HBase 底层文件系统。
ZooKeeper 是一个可靠的高可用的、持久化的分布式的协调系统,它在 HBase 的架构中是监控服务器可用性、跟踪机器故障和网络分区。每台 Region 服务器在 ZooKeeper 服务器中会有独立的会话,Region 作为客户端会向 ZooKeeper 服务器定时发送”心跳“,以判断服务器是否故障。
1. HBase 基础
1.1 HBase 数据访问
HBase 基础的数据访问,通过 get()
和 scan()
方法可以实现指定列族、列、时间戳以及版本号的筛选。这种方式的筛选访问得到的数据是粗粒度数据,不是细粒度方式的筛选,eg: 正则表达式的筛选。在客户端 HBase 的可以通过支持的 Filter 进行行键、列名或者列值过滤,在服务器收到筛选需求需要通过谓词下推的方式实施筛选。虽然在客户端实施筛选,但会增加数据传输压力影响性能。
1.2 版本管理和数据删除
在同一个单元格多次写入数据时,HBase 的数据会有不同的版本。在进行数据操作时,可以是隐式的进行版本管理,也可以进行显性的版本管理。
在进行删除操作时,是对特定的时间戳添加一个一个墓碑标记,它会屏蔽指定的对应版本的数据(隐式处理的情况下是直接给最大时间戳的版本数据),在刷写缓存或 major 合并动作之前老版本的数据就会出现(刷写或者合并之后,数据会真实删除)
1.3 自定义版本控制
自定义的版本控制,可以覆盖服务器时间戳为基础的版本控制。例如由 ZooKeeper 提供的全局数字生成器可以在调用 put 操作时提供以 1 开始增加的顺序数字。使用自定义版本控制,可以通过为每个 put 使用数字生成器,或者在表、列的描述标志中表明使用自定义的时间戳。
需要这样如果没有设置生成器值,那么将在服务器被时间戳替换掉,此外某些自定义时间戳的方式需要验证是否可用(例如负值时间戳是否可用,最好验证一次)。
自定义版本控制设置模式:
- 记录 ID,以时间戳作为存储消息 ID,因为 HBase 的版本隐式排序是降序排序方式,因此可以通过这种 ID 排序方式筛选得到最后 N 个版本的数据
- 数字生成器 它和时间戳的功能意义上差异不大,都是提供能够区别版本的依据。但是在应用层面上存在较大差异,前者能够提供完全相同时间戳的版本数据,而后者因为 Java 计时器使用的精度是毫秒,难以实现筛选完全相同时间戳版本数据。
HBase 优化
HBase 的数据分片以及在 HFile 数据拆分时,都是通过行来进行拆分,因此在表创建时高表方案会更有优势。而在查询方面也会有相应的优化。
数据读写热点优化
在某些场景下,例如流式数据处理过程时,HBase 的数据组织方式会让有序的数据会被过份集中到“某个” region 服务器下。这样的存储会导致读写热点,同时因为这种数据过份集中会是系统性能下降。
要解决该问题可以通过将数据分散到所有的服务器中,其中一种方法就是采用 Salting 的方法:方法是在键的前端会从一定序列中的某个元素添加到键前端,这样打乱有序 key 的方式可以优化该问题。
1 | # 该代码思路是 Mozilla Socrro 思路,在键上从 16 个字符中分别添加到键中去组合成新键 |
通过字段交换或者权重提升的方法也是一种优化行键的方案,思路是将时间戳字段一开户添加其他字段作为前缀产生组合行键的思路:对连续递增的时间戳从行键的第一位置变为第二位置来处理。
第三种方案是通过随机化的方式,即利用如 MD5 的随机化函数将行键进行散列。缺点是不能再通过时间范围扫描数据。
2. Python 使用 HBase
HBase 客户端包括 Thrift、REST 等类型,Python 访问需要通过 Thrift 客户端形式访问(Java 可以直接配置 zookeeper 信息,以 zookeeper 连接访问)。
2.1 用 Thrift 访问 HBase
happybase
提供了封装 Thrift 访问的方式,直接以 connection = happybase.Connetion(host='host', port=9090)
形式访问可能会出现异常: TTransportException: TTransportException
和 TTransportException: TSocket read 0 bytes
。这个问题需要检查一下 HBase 和 Thrift 的配置信息:
1 | <property> |
因为上面 hbase.regionserver.thrift.framed
和 hbase.regionserver.thrift.compact
配置信息和 happybase
连接中默认配置信息不一致,需要进行调整相关的参数值:
1 | import happybase |
3. 其他概念
3.1 HBase 解编码器
HBase 提供的不同压缩算法对压缩比、CPU 消耗以及解压效率等方面表现不同,因此选择不同的压缩方案是由重要的实践意义:
- Snappy
Google 发布的 BSD 协议压缩压缩算法,在压缩率和解压效率都较高 - LZO
Lempel-Ziv-Oberhumer ,一种无损压缩算法,在解压效率较高 - GZIP
压缩效率较高,能够减少存储空间开销,但是速度偏慢,通过本地操作系统的 GZIP 库可以缓解性能问题——如果本地库不存在,那么会收到 “Got brand-new compresser” 日志信息。但是它是 CPU 密集型算法性能会受到严重影响,因此服务器的负载会加大
1 | // 表创建时申明启用压缩 |